package com.tebiecloud.mpweixin.server.controller.feign;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.tebiecloud.common.constants.ResultEnum;
import com.tebiecloud.common.model.ResultBody;
import com.tebiecloud.common.utils.JsonUtils;
import com.tebiecloud.common.utils.ResultBodyUtils;
import com.tebiecloud.common.utils.StringUtils;
import com.tebiecloud.mpweixin.client.model.entity.MpweixinUser;
import com.tebiecloud.mpweixin.client.model.mpweixin.QrcodeTicket;
import com.tebiecloud.mpweixin.client.model.mpweixin.RespBase;
import com.tebiecloud.mpweixin.client.service.IMpweixinApiServiceClient;
import com.tebiecloud.mpweixin.server.properties.MpweixinProperties;
import com.tebiecloud.mpweixin.server.service.MpweixinApiService;
import com.tebiecloud.mpweixin.server.service.MpweixinUserService;
import com.tebiecloud.mpweixin.server.service.feign.MpopenApiServiceClient;
import com.tebiecloud.mpweixin.server.utils.MPApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * 公众号接口
 * @Author: tebie
 * @Date: 2019-09-10 12:05
 */
@Slf4j
@RestController
@RequestMapping("/feign/api")
public class ApiController implements IMpweixinApiServiceClient {

    @Autowired
    private MpweixinProperties mpweixinProperties;

    @Autowired
    private MpweixinUserService mpweixinUserService;

    @Autowired
    private MpweixinApiService mpweixinApiService;

    @Autowired
    private MpopenApiServiceClient mpopenApiServiceClient;

    /**
     * 网页授权，拉取用户信息(需scope为 snsapi_userinfo)
     * @param appid
     * @param openid
     * @param accessToken
     * @return
     */
    @PostMapping("infoMpweixinUser")
    @Override
    public ResultBody<MpweixinUser> getMpweixinUser(
            @RequestParam("appid") String appid,
            @RequestParam("openid") String openid,
            @RequestParam("accessToken") String accessToken) {
        MpweixinUser mpweixinUser = mpweixinApiService.getMpweixinUser(accessToken, openid);
        if(mpweixinUser != null && !StringUtils.isEmpty(mpweixinUser.getOpenid())) {
            // 不存在粉丝时插入数据
            QueryWrapper<MpweixinUser> queryWrapper = new QueryWrapper<MpweixinUser>();
            queryWrapper.eq("appid", appid);
            queryWrapper.eq("openid", mpweixinUser.getOpenid());
            queryWrapper.last("LIMIT 1");
            MpweixinUser mpweixinUser1 = mpweixinUserService.getOne(queryWrapper);
            if(mpweixinUser1 == null) {
                mpweixinUser.setAppid(appid);
                mpweixinUserService.save(mpweixinUser);
            }else{
                //如果原来的信息没有存在，则更新
                if(StringUtils.isNotEmpty(mpweixinUser1.getNickname())|| StringUtils.isNotEmpty(mpweixinUser1.getHeadimgurl())){
                    UpdateWrapper<MpweixinUser> mpweixinUserUpdateWrapper = new UpdateWrapper<>();
                    mpweixinUserUpdateWrapper.eq("openid",mpweixinUser1.getOpenid());
                    MpweixinUser updateEntity = new MpweixinUser();
                    updateEntity.setNickname(mpweixinUser.getNickname());
                    updateEntity.setHeadimgurl(mpweixinUser.getHeadimgurl());
                    mpweixinUserService.update(updateEntity,mpweixinUserUpdateWrapper);
                }
            }
            return ResultBodyUtils.ok(mpweixinUser);
        }

        return ResultBodyUtils.failed();
    }

    /**
     * 创建二维码
     * @param data QrcodeParam类对应的json字符串
     * @return
     */
    @PostMapping("createQrcode")
    @Override
    public ResultBody<QrcodeTicket> createQrcode(@RequestParam("data") String data) {
        String appid = mpweixinProperties.getAppid();
        QrcodeTicket qrcodeTicket = getQrcodeTicket(appid, data, false);
        if(qrcodeTicket != null && MPApi.isInvalueToken(qrcodeTicket.getErrcode())) {
            log.info("access_token无效，重新获取");
            qrcodeTicket = getQrcodeTicket(appid, data, true);
        }

        if(qrcodeTicket != null && !StringUtils.isEmpty(qrcodeTicket.getUrl())) { // access_token无效，重新获取
            return ResultBodyUtils.ok(qrcodeTicket);
        }

        log.info("生成微信二维码失败");
        return ResultBodyUtils.failed();
    }

    /**
     * 获取微信二维码
     * @param appid
     * @param data
     * @param force
     * @return
     */
    private QrcodeTicket getQrcodeTicket(String appid, String data, boolean force) {
        ResultBody<String> respAccessToekn = mpopenApiServiceClient.getWxapiAccessToken(appid, force);
        if(respAccessToekn.getCode() != ResultEnum.OK.getCode()) {
            log.info("生成微信二维码失败, respAccessToekn: {}", JsonUtils.Obj2Str(respAccessToekn));
            return null;
        }
        String access_token = respAccessToekn.getData();
        String resp = MPApi.qrcodeCreate(access_token, data);
        QrcodeTicket qrcodeTicket = JsonUtils.str2Bean(resp, QrcodeTicket.class);
        if(qrcodeTicket != null) {
            return qrcodeTicket;
        }

        return null;
    }

    /**
     * 推送微信消息
     * @param data SendMpMsgInfo类对应的json字符串
     * @return
     */
    @PostMapping("sendMpMsg")
    @Override
    public ResultBody sendMpMsg(@RequestParam("data") String data) {
        String appid = mpweixinProperties.getAppid();

        RespBase respBase = sendMpMsg(appid, data, false);
        if(respBase != null && MPApi.isInvalueToken(respBase.getErrcode())) {
            log.info("access_token无效，重新获取");
            respBase = sendMpMsg(appid, data, true);
        }

        if(respBase != null && respBase.getErrcode() == 0) {
            return ResultBodyUtils.ok(respBase);
        }

        log.info("生成微信二维码失败");
        return ResultBodyUtils.failed();
    }

    /**
     * 推送微信消息
     * @param appid
     * @param data
     * @param force
     * @return
     */
    private RespBase sendMpMsg(String appid, String data, boolean force) {
        ResultBody<String> respAccessToekn = mpopenApiServiceClient.getWxapiAccessToken(appid, force);
        if(respAccessToekn.getCode() != ResultEnum.OK.getCode()) {
            log.info("发送微信消息失败, respAccessToekn: {}", JsonUtils.Obj2Str(respAccessToekn));
            return null;
        }

        String resp = MPApi.postMessageCustom(respAccessToekn.getData(), data);
        RespBase respBase = JsonUtils.str2Bean(resp, RespBase.class);
        if(respBase != null) {
            return respBase;
        }

        return null;
    }

}
